#!/usr/bin/env python
# -*- coding: UTF-8 -*-
##
##    Copyright (C) 2005 manatlan manatlan[at]gmail(dot)com
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 2 only.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##

"""

"""

import gtk
import gobject
import os,sys
import time
import datetime

from fricorder import FConfig
from fricorder import fbx
from fricorder import common
from fricorder import progtv
from fricorder import dict4ini
from fricorder import api
from fricorder.gladeapp import GladeApp


def MessageBox(parent,data,title="fricorder message"):
    dialog = gtk.Dialog(title, parent, 0,
            (gtk.STOCK_OK, gtk.RESPONSE_OK)
            )
    dialog.set_default_response(gtk.RESPONSE_OK)

    hbox = gtk.HBox(False, 8)
    hbox.set_border_width(8)
    dialog.vbox.pack_start(hbox, False, False, 0)

    stock = gtk.image_new_from_stock(
            gtk.STOCK_DIALOG_INFO,
            gtk.ICON_SIZE_DIALOG)
    hbox.pack_start(stock, False, False, 0)

    table = gtk.Table(2, 2)
    table.set_row_spacings(4)
    table.set_col_spacings(4)
    hbox.pack_start(table, True, True, 0)

    label = gtk.Label(data)
    label.set_selectable(True)
    table.attach(label, 0, 2, 0, 1)

    dialog.show_all()

    response = dialog.run()

    dialog.destroy()



class Window1(GladeApp):
    glade=os.path.join(os.path.dirname(__file__), os.path.join(FConfig.DATADIR,'fricorder.glade'))
    window="window1"

    def init(self):
        self.cfg = dict4ini.DictIni(FConfig.CONFIGFILE)

        # initialise le progtv, si il est defini dans le ~/.fricorder
        if self.cfg.config.xmltv and os.path.isfile(self.cfg.config.xmltv):
            progtv.init(self.cfg.config.xmltv)

        # maj de la liste des chaines
        cell = gtk.CellRendererText()
        self.cb_chaine.pack_start(cell, False)
        self.cb_chaine.add_attribute(cell, 'text',4)
        cell = gtk.CellRendererText()
        self.cb_chaine.pack_start(cell, True)
        self.cb_chaine.add_attribute(cell, 'text',0)
        cell = gtk.CellRendererText()
        self.cb_chaine.pack_start(cell, False)
        self.cb_chaine.add_attribute(cell, 'text',3)

        l = fbx.getStreams()
        m=gtk.ListStore( str,str,str,str,str)
        m.clear()
        for num,chaine,url in l:

            chaineTV = fbx.convChaine(chaine)
            if not progtv.isPresent(chaineTV):
                chaineTV=None

            m.append( [chaine,common.normalize(chaine),url,chaineTV,"%d)"%num] )
        self.cb_chaine.set_model(m)

        # maj du bouton progtv
        self.b_progtv.set_sensitive(False)
        if not progtv.isAvailable():
            # si pas de chaines dans le progtv : pas de bouton
            self.b_progtv.hide()

        # maj de la combobox quality
        cell = gtk.CellRendererText()
        self.cb_quality.pack_start(cell, True)
        self.cb_quality.add_attribute(cell, 'text',0)
        m=gtk.ListStore( str,)
        m.clear()
        for i in api.getQualite():
            m.append( [i,] )
        self.cb_quality.set_model(m)

        # maj de la list des "enregistrements prevus"
        column = gtk.TreeViewColumn("Chaine", gtk.CellRendererText(),text=1,foreground=6)
        self.tv_list.append_column(column)
        column = gtk.TreeViewColumn("Date", gtk.CellRendererText(),text=2,foreground=6)
        self.tv_list.append_column(column)
        column = gtk.TreeViewColumn("Début", gtk.CellRendererText(),text=3,foreground=6)
        self.tv_list.append_column(column)
        column = gtk.TreeViewColumn("Fin", gtk.CellRendererText(),text=4,foreground=6)
        self.tv_list.append_column(column)

        renderer = gtk.CellRendererToggle();
        renderer.set_data("column", 7)
        renderer.connect("toggled", self.on_item_toggled)
        column = gtk.TreeViewColumn("Shutdown", renderer,
                                       active=7,
                        )
        column.set_clickable(True)
        self.tv_list.append_column(column)

        # 0:code, 1:chaine,2:date,3:heure,4:fin,5:fileId,6:color,7:isHalt
        m=gtk.ListStore( str,str,str,str,str,str,str,bool)
        self.tv_list.set_model(m)
        self.fillAt()


        # maj des spinbox heure de debut
        self.date = datetime.datetime.now()
        self.sb_heure.set_value( self.date.hour )
        self.sb_min.set_value( self.date.minute )

        # maj de la combobox des jours
        cell = gtk.CellRendererText()
        self.cb_jour.pack_start(cell, True)
        self.cb_jour.add_attribute(cell, 'text',0)
        m=gtk.ListStore( str, )
        m.clear()
        for num,jour in api.getJours(self.date,14):
            m.append( [common.affDate(jour),] )
        self.cb_jour.set_model(m)
        self.cb_jour.set_active(0)

        # restore la config
        self.cb_quality.set_active( self.cfg.config.quality or 0)
        self.e_dest.set_text( self.cfg.config.destination or os.getenv("HOME", ""))
        self.sb_time.set_text( self.cfg.config.minutes or "30")

        #~ self.main_widget.resize( 300,150 )
        self.timer = gobject.timeout_add (1000, self.refresh)

        self.main_widget.set_title("fricorder %s by manatlan" % FConfig.VERSION)

    def on_item_toggled(self, cell, path_str):
        model = self.tv_list.get_model()
        iter = model.get_iter_from_string(path_str)
        api.FileId.toggleHaltFileName( model.get_value(iter, 5) )
        self.fillAt()

    def refresh(self):
        self.fillAt()
        return True

    def fillAt(self):
        treeselection = self.tv_list.get_selection()
        if treeselection:
            m, iter0 = treeselection.get_selected()
            path = iter0 and m.get_path(iter0) or None

            m=self.tv_list.get_model()
            m.clear()
            for code,chaine,deb,duree in api.getAtList():
                date = common.affDate(deb)
                heure = deb.strftime("%H:%M")
                fin = (deb+datetime.timedelta(minutes=duree)).strftime("%H:%M")
                fileId = api.FileId.make(chaine,deb,duree)

                file=api.FileId.genPidFileName(fileId)
                if os.path.isfile(file):
                    color="red"
                else:
                    color="black"

                isHalt= api.FileId.isHaltFileName(fileId)

                # 0:code, 1:chaine,2:date,3:heure,4:fin,5:fileId,6:color,7:isHalt
                m.append( [code,chaine,date,heure,fin,fileId,color,isHalt] )

            if path:
                treeselection.select_path(path)

    def quitte(self):
        # set config file
        self.cfg.config.quality = self.cb_quality.get_active()
        self.cfg.config.destination = self.e_dest.get_text()
        self.cfg.config.minutes = self.sb_time.get_text()
        self.cfg.save()

        # and bye bye
        self.quit()

    def on_window1_delete_event(self, widget, *args):
        self.quitte()

    def on_sb_time_changed(self, widget, *args):
        newval = widget.get_text()
        if newval:
            debut = datetime.datetime(self.date.year,self.date.month,self.date.day,int(self.sb_heure.get_value()),int(self.sb_min.get_value()),0)
            debut+=datetime.timedelta(minutes=int(newval))
            self.e_fin.set_text( debut.strftime("%H:%M") )


    def on_b_progtv_clicked(self, widget, *args):
        idx = self.cb_chaine.get_active_iter()
        if idx:
            model=self.cb_chaine.get_model()

            chaineFBX = model.get_value(idx,0)
            chaineTV = model.get_value(idx,3)
            date =self.date+datetime.timedelta(days=self.cb_jour.get_active())

            winprog = Winprog(self,chaineTV,date,chaineFBX)
            winprog.loop()

    def on_debut_changed(self, widget, *args):
        self.on_sb_time_changed(self.sb_time)

    def on_prog_changed(self, widget, *args):
        idx = self.cb_chaine.get_active_iter()
        if idx:
            model=self.cb_chaine.get_model()

            chaineTV = model.get_value(idx,3)
            date =self.date+datetime.timedelta(days=self.cb_jour.get_active())

            if progtv.isPresent(chaineTV,date):
                self.b_progtv.set_sensitive(True)
            else:
                self.b_progtv.set_sensitive(False)

    def on_btn_dest_clicked(self, widget, *args):
        dialog = gtk.FileChooserDialog ("Choisir le répertoire de Destination",
             None, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
             (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN,
              gtk.RESPONSE_OK))
        dialog.set_default_response (gtk.RESPONSE_OK)
        #~ dialog.set_transient_for (self.dlg_add)

        # preselect the previous mount point
        dialog.select_filename (self.e_dest.get_text())

        response = dialog.run ()
        if response == gtk.RESPONSE_OK:
              self.e_dest.set_text( dialog.get_filename() )

        dialog.destroy()

    def on_btn_valid_clicked(self, widget, *args):
        idx = self.cb_chaine.get_active_iter()
        if not idx:
            MessageBox(self.main_widget,"Vous devez selectionner une chaine")
        else:
            model=self.cb_chaine.get_model()
            chaine = model.get_value(idx,1)
            stream = model.get_value(idx,2)

            quality= self.cb_quality.get_active_text()

            destination = self.e_dest.get_text()
            if not os.path.isdir(destination):
                MessageBox(self.main_widget,"Le répertoire de destination n'existe pas")
            else:
                debut = datetime.datetime(self.date.year,self.date.month,self.date.day,int(self.sb_heure.get_value()),int(self.sb_min.get_value()),0)
                debut= debut+datetime.timedelta(days=self.cb_jour.get_active())
                duree = int(self.sb_time.get_text())

                err=api.runAt(stream,chaine,quality,debut,duree,destination)
                if not err:
                    time.sleep(1)
                    self.fillAt()
                else:
                     MessageBox(self.main_widget,err)



    def on_tv_list_button_release_event(self, widget, *args):
        #~ if args[0].button == 3:
        pass

    def on_btn_supprimer_clicked(self, widget, *args):
        treeselection = self.tv_list.get_selection()
        model, iter0 = treeselection.get_selected()
        if not iter0:
            MessageBox(self.main_widget,"Vous devez selectionner un enregistrement")
        else:
            code= model.get_value(iter0,0)
            fileid= model.get_value(iter0,5)
            api.cancelJob(code,fileid)

            self.fillAt()

    def on_btn_quitter_clicked(self, widget, *args):
        self.quitte()


class Winprog(GladeApp):

    glade=os.path.join(os.path.dirname(__file__), os.path.join(FConfig.DATADIR,'fricorder.glade'))
    window="winprog"

    def init(self,parent,chaineTV,date,chaine):
        self.main_widget.resize( 300,400 )

        column = gtk.TreeViewColumn("Horaire", gtk.CellRendererText(),text=0)
        self.progs.append_column(column)
        column = gtk.TreeViewColumn("Duree", gtk.CellRendererText(),text=2)
        self.progs.append_column(column)
        column = gtk.TreeViewColumn("Titre", gtk.CellRendererText(),text=1)
        self.progs.append_column(column)

        # 0:heure, 1:titre,2:duree
        m=gtk.ListStore( str,str,int)
        self.progs.set_model(m)
        self.main_widget.set_keep_above(True)

        self.parent = parent
        self.date = date
        m=self.progs.get_model()
        m.clear()

        self.main_widget.set_title("Programme TV - %s %s" % (chaine,common.affDate(date)))
        progs = progtv.getProgs(chaineTV,date)
        for dt,duree,titre in progs:
            m.append([dt.strftime("%H:%M"),titre, duree])

    def on_winprog_delete_event(self, widget, *args):
        # close the window
        self.quit()

    def on_progs_button_press_event(self, widget, *args):
        event=args[0]
        if event.button==1 and event.type == gtk.gdk._2BUTTON_PRESS:
            treeselection = self.progs.get_selection()
            model, iter0 = treeselection.get_selected()
            if iter0:
                h,m=model.get_value(iter0,0).split(":")
                #~ date= datetime.datetime(self.date.year,self.date.month,self.date.day,int(h),int(m),0)
                titre= model.get_value(iter0,1)
                duree= model.get_value(iter0,2)
                #~ print date,duree,titre
                self.parent.sb_heure.set_value(int(h))
                self.parent.sb_min.set_value(int(m))
                self.parent.sb_time.set_value(duree)
                self.quit()


def main():
    if api.isAtdRunning():
        GladeApp.setDefaultIcon(os.path.join(FConfig.DATADIR,"fricorder.png"))
        window1 = Window1()

        window1.loop()
    else:
        MessageBox(None,"Le démon ATD ne semble pas tourner sur votre ordinateur, par conséquent fricorder ne sera pas utilisable.")

if __name__ == "__main__":
    main()
